var c  = document.getElementById('c'), ctx = c.getContext('2d'), w = 20, h = 20, pw = c.width / w, ph = c.height / h;
var D = {97: {x: -1, y: 0}, 115: {x: 0, y: 1}, 100: {x: 1, y: 0}, 119: {x: 0, y: -1}}; // A:97, S:115, D:100, W:119
var pb = [{x: parseInt(w / 2, 10), y: parseInt(h / 2, 10), d: 119}], pf = rndp();
window.addEventListener('keypress', function (e) { if (D[e.which]) pb[0].d = e.which; });
ctx.mdo = function (f, a) { return ctx[f].apply(ctx, a), ctx; };
ctx.mset = function (f, v) { return ctx[f] = v, ctx; };
function drawPoint (p, a, b, color) { ctx.mset('strokeStyle', '#fff').mdo('strokeRect', [p.x * pw, p.y * ph, pw, ph]).mset('fillStyle', color || '#aaa').mdo('fillRect', [p.x * pw, p.y * ph, pw, ph]); }
function rndp () {
  var p = {x: parseInt(Math.random() * w, 10), y: parseInt(Math.random() * h, 10)};
  return pb.some(function (p2) { return p.x === p2.x && p.y === p2.y; }) ? rndp() : p;
}
function gover () { ctx.mset('fillStyle', '#e96900').mset('font', 'bold 24px 宋体').mdo('fillText', ['游戏结束', (c.width - 24 * 4) / 2, (c.height - 24) / 2]); }
function nxp (p) {
  var d = D[p.d];
  return {x: p.x + d.x, y: p.y + d.y, d: p.d};
}
function gloop () {
  var hp = nxp(pb[0]); // 计算前进后蛇头的位置，如果不在屏幕区域内，或者与蛇身重合，则游戏结束
  if (!(hp.x >= 0 && hp.x < w && hp.y >= 0 && hp.y < h)) return gover();
  for (var i = 0; i < pb.length; i++) if (hp.x === pb[i].x && hp.y === pb[i].y) return gover();
  pb.unshift(hp); // 没有吃到食物，蛇头前进时，蛇尾要收缩
  (pf.x === hp.x && pf.y === hp.y) ? pf = rndp() : pb.pop();
  ctx.mset('fillStyle', '#f1fedd').mdo('fillRect', [0, 0, c.width, c.height]);
  drawPoint(pf, 0, 0, '#e96900'); // 食物
  drawPoint(pb[0], 0, 0, '#2d64b3'); // 蛇头
  pb.slice(1).forEach(drawPoint); // 舍身
  tid = setTimeout(gloop, 200 - pb.length * 1.5); // 自动加快速度
}
var tid = setTimeout(gloop, 200);